import axios, {AxiosProgressEvent, AxiosResponse, InternalAxiosRequestConfig} from 'axios'
import {getToken, logout, removeToken, setToken} from "@/utils/auth";
import global from "@/dict/global";
import {ElLoading} from "element-plus";
import {msgError} from "@/utils/alert";


let loading: any;
const startLoading = () => {
    loading = ElLoading.service({
        background:'rgba(0, 0, 0, 0.5)',
        lock:true,
        text:'请稍候……'
    })
}
const stopLoading = () => {
    loading.close()
}

let refreshTokenComplete = true
let requestQueues :any[] = []

axios.defaults.baseURL = import.meta.env.VITE_APP_BASE_API
axios.defaults.timeout = 50000

// request拦截器
axios.interceptors.request.use((config: InternalAxiosRequestConfig) => {

    // startLoading()

    // adminToken设置
    const adminToken = getToken(global.adminToken)
    if (adminToken) {
        config.headers['Authorization'] = "Bearer " + adminToken // 让每个请求携带自定义token 请根据实际情况自行修改
    }
    return config

}, error => {

    // startLoading()

    return Promise.reject(error)
})

// 响应拦截器
axios.interceptors.response.use((response: AxiosResponse) => {

    let error: number = response.data?.error
    let errMsg: string = response.data.msg


    // 二进制数据则直接返回
    // if (response.request && (response.request.responseType === 'blob' || response.request.responseType === 'arraybuffer')) {
    //     return response
    // }

    if (error == 10001){    // 令牌过期，尝试再次请求一次

        if (refreshTokenComplete){  // 没有正在刷新令牌的请求，刷新令牌
            refreshTokenComplete = false
            // 刷新令牌
            return axios.post('/open.public/refreshToken', {}).then(res => {     // 令牌刷新成功
                const token = res.data.token
                // 设置新token
                setToken(global.adminToken, token)
                // 读取请求队列，并重新发送请求
                requestQueues.forEach((callback) => callback())
                // 清空队列
                requestQueues = []
                // 重新发送当前请求
                return axios(response.config)

            }).catch(err => {
                // 刷新令牌失败，重新登录
                // 清空队列
                requestQueues = []
                // 退出登录
                logout()
                return Promise.reject(err)

            }).finally(() => {
                refreshTokenComplete = true
            })

        }else{  // 有正在刷新令牌的请求，将请求加入等待队列
            return new Promise(resolve => {
                requestQueues.push(() => {
                    resolve(axios(response.config))
                })
            })
        }
    }else if (error != 0){
        return Promise.reject(errMsg)
    }
    return response

}, error => {

    // loading
    // stopLoading()

    console.log("error",error)

    let {message} = error;

    // if (message == "Network Error") {
    //     message = "后端接口连接异常";
    // } else if (message.includes("timeout")) {
    //     message = "系统接口请求超时";
    // } else if (message.includes("Request failed with status code")) {
    //     message = "系统接口" + message.substr(message.length - 3) + "异常";
    // }

    // 返回
    return Promise.reject(message)
})

export const request = axios

export const simpleGet  = (url:string, params:object = {}) : Promise<any>  => {

    return new Promise(resolve => {
        axios.get(url, {params:params}).then(r => {
            resolve(r.data)
        }).catch(e => {
            msgError(e)
        })
    })
}


export const simplePost = (url:string, data:object = {}) : Promise<any> => {

    return new Promise(resolve => {
        axios.post(url, data).then(r => {
            resolve(r.data)
        }).catch(e => {
            msgError(e)
        })
    })

}

// 刷新令牌
export const refreshToken = () => {
    return new Promise<any>(resolve => {
        return axios.post('/open.public/refreshToken', {}).then(res => {     // 令牌刷新成功
            const token = res.data.token
            // 设置新token
            setToken(global.adminToken, token)
            // 返回数据
            resolve(res)
        }).catch(err => {
            // 刷新令牌失败，重新登录
            // 退出登录
            logout()
        }).finally(() => {
            // refreshTokenComplete = true
        })
    })

}


/**
 * 导出下载
 * @param url
 * @param where
 */
export const download = (url:string, where:any = {}) => {
    startLoading()
    where = where||{}
    let res = axios.post(url, where,{
        responseType: 'blob',
        onDownloadProgress: (progressEvent: AxiosProgressEvent) =>{
            // 文件总大小
            const size = progressEvent.event.currentTarget.response?.size
            //progressEvent.loaded 下载文件的当前大小
            //progressEvent.total  下载文件的总大小 如果后端没有返回 请让他加上！
            let progressBar = Math.round( progressEvent.loaded / size * 100);
            //接收进度为99%的时候需要留一点前端编译的时间
            if(progressBar >= 100){
                stopLoading()
                // this.percentage = 99;
                // this.$message.success("下载完成，文件正在编译。");
                // this.title = '下载完成，文件正在编译。';
            }else{
                // this.percentage = progressBar;
                // this.$message("正在下载，请稍等。");
                // this.title = '正在下载，请稍等。';
            }
            // console.log(progressEvent)
        },
    }).then((res) => {

        let disposition = res.headers['content-disposition']
        let filename = decodeURI(disposition.substring(disposition.lastIndexOf("filename*=UTF-8''")+17, disposition.length))
        let blob = new Blob([res.data])

        // @ts-ignore
        if (window.ActiveXObject || "ActiveXObject" in window){ // ie浏览器
            // @ts-ignore
            navigator.msSaveBlob(blob, filename)
        }else{
            const elink: any = document.createElement('a')
            elink.download = filename
            elink.style.display = 'none'
            elink.href = URL.createObjectURL(blob)
            document.body.appendChild(elink)
            elink.click()
            URL.revokeObjectURL(elink.href) // 释放URL 对象
            document.body.removeChild(elink)
        }

        // stopLoading()

    }).catch((err) => {
        stopLoading()
    })

}
